 /*
 * All action in this controller will be called asynchronously by client browser.
 */
class InstallController {
	
	//
	boolean isSaveSuccess = true

	/**
	 * Control displaying on page.
	 */
    def index = {
		render(view:'install', 
			model:[
				'needInitDemoData': grailsApplication.config.modules.install.needInitDemoData, 
				'needInitTestData': grailsApplication.config.modules.install.needInitTestData,
				'needInitAllData': grailsApplication.config.modules.install.needInitAllData,
				'needClearAllData': grailsApplication.config.modules.install.needClearAllData
				])
	}

	/**
	 * Clear all data in database.
	 */
	def clearAllData = {
		if( !needClearAllData) {
			render('Warring: clear all data will cause system unavailable, you are not allowed to do so.')
			
		} else {
			def exists = User.findAll()
			for(User u in exists){
				u.delete(flush:true)
			}
			render('User data clear<br/>')

			exists = Role.findAll()
			for(Role r in exists){
				r.delete(flush:true)
			}
			render('Role data clear<br/>')

			exists = Privilege.findAll()
			for(Privilege p in exists){
				p.delete(flush:true)
			}
			render('Privilege data clear<br/>')

			
			render('All data cleared!<br/>')
		}
	}
	
	/**
	 * Init all data.
	 */
	def initAllData = {
		initSystemData()
		initDataForDemo()
		initDataForTest()		
	}

	/**
	 * Init system data.
	 */
	def initSystemData = {
		log.info 'Start to install default data'
		isSaveSuccess = true
		
		initPrivileges()
			
		initRoles()

		initSystemUser()

		if( isSaveSuccess ) {
			render( 'System Data Created<br/>')
		}
	}

	/**
	 * Init data for demo, implemented by inheritor.
	 */
	def initDataForDemo = {
		if( grailsApplication.config.modules.install.needInitDemoData == false ) {
			println 'No data for demo to init.'
			return false
		}
		
		// TODO Add demo data init code here.
		render('Demo Data Created!')
	}

	/**
	 * Init data for test.
	 */
	def initDataForTest = {
		if( grailsApplication.config.modules.install.needInitTestData == false ) {
			println 'No data for test to init.'
			return false
		}
		// TODO Add test data init code here.
		render('Test Data Created!<br/>')
	}

	/**
	 * Init for system default privileges.
	 * @return
	 */
	def initPrivileges(){
		render('Init Privileges...')
		// USER
		saveEntityWithMessageRenderred( new Privilege(privName:'SHOW_USER',description:''))
		saveEntityWithMessageRenderred( new Privilege(privName:'CREATE_USER',description:''))
		saveEntityWithMessageRenderred( new Privilege(privName:'UPDATE_USER',description:''))
		saveEntityWithMessageRenderred( new Privilege(privName:'DELETE_USER',description:''))
		render('.')
		
		// ROLE
		saveEntityWithMessageRenderred( new Privilege(privName:'SHOW_ROLE',description:''))
		saveEntityWithMessageRenderred( new Privilege(privName:'CREATE_ROLE',description:''))
		saveEntityWithMessageRenderred( new Privilege(privName:'UPDATE_ROLE',description:''))
		saveEntityWithMessageRenderred( new Privilege(privName:'DELETE_ROLE',description:''))
		render('.')
		
		// PRIVILEGE
		saveEntityWithMessageRenderred( new Privilege(privName:'SHOW_PRIVILEGE',description:''))
		saveEntityWithMessageRenderred( new Privilege(privName:'CREATE_PRIVILEGE',description:''))
		saveEntityWithMessageRenderred( new Privilege(privName:'UPDATE_PRIVILEGE',description:''))
		saveEntityWithMessageRenderred( new Privilege(privName:'DELETE_PRIVILEGE',description:''))
		render('.')

		//
		saveEntityWithMessageRenderred( new Privilege(privName:'SYSTEM_SETTING ',description:''))

		if(isSaveSuccess) {
			render('done.<br/>')
		}
	}

	/**
	 * Init for system default Roles
	 * @return
	 */
	def initRoles() {
		render('Init Roles...')
		
		String rootRoleName = grailsApplication.config.modules.role.root.name
		
		def privileges = Privilege.findAll()
		if(!Role.findByRoleName(rootRoleName)){
			saveEntityWithMessageRenderred(new Role(roleName:rootRoleName, description:'Administrator', privileges:privileges))
		}
		
		if(!Role.findByRoleName('Guest')){
			saveEntityWithMessageRenderred(new Role(roleName:'Guest', description:'Guest', privileges: null))
		}
		
		if(isSaveSuccess) {
			render('done.<br/>')
		}
	}

	/**
	 * Init system user.
	 * @return
	 */
	def initSystemUser() {
		render('Init System User...')
		
		String rootRoleName = grailsApplication.config.modules.role.root.name
		def u = new User(userName:grailsApplication.config.modules.user.root.name, password:'admin', firstName:'Administrator', creationTime: Calendar.getInstance())
		def r = Role.findByRoleName(rootRoleName)
		
		println "role: ${r}"
		if(r){
			u.roles = [r]
		}
		saveEntityWithMessageRenderred(u)
		
		if(isSaveSuccess) {
			render('done.<br/>')
		}
	}

	/**
	 * Save new created entity with error message rendered if fail.
	 * @param entity
	 */
	protected void saveEntityWithMessageRenderred(entity) {
		if(entity.hasErrors()){
			println "Entity ${entity} has errors"
			entity.errors.allErrors.each{
				println it
				if(it){
					render('<br/>')
					render(it)
					render('<br/><br/>')
				}
			}
			isSaveSuccess = false
			
		} else {
			if(!entity.save(flush:true)){
				println "Save entity ${entity} with errors"
				entity.errors.allErrors.each{
					println it
					if(it){
						render('<br/>')
						render(it)
						render('<br/><br/>')
					}
				}
				isSaveSuccess = false
			}
		}
	}

}
